﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using uPLibrary.Networking.M2Mqtt;

namespace WOLController
{
    public partial class Form1 : Form
    {
        public string mqtt_server = "119.91.90.201";
        public int mqtt_port = 1883;
        public string username = "guest";
        public string password = "guest";
        public string clientId = "wol_controller";
        MqttClient client;

        public Form1()
        {
            InitializeComponent();
        }


        void Reconnect()
        {
            //client = ConnectMQTT(mqtt_server, mqtt_port, clientId, username, password);
            client.Connect(clientId, username, password);

            client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
            client.ConnectionClosed += Client_ConnectionClosed;
            client.Subscribe(new string[] { "hw/home/wol" }, new byte[] { 0 });

            if (client.IsConnected)
            {
                Console.WriteLine("Connected to MQTT Broker");
            }
            else
            {
                Console.WriteLine("Failed to connect");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            client = new MqttClient(mqtt_server);
            Reconnect();
        }

        private void Client_MqttMsgPublishReceived(object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishEventArgs e)
        {
            //throw new NotImplementedException();
            listBox1.Items.Add(e.Topic);
            WakeUp(e.Message);
        }

        private void Client_ConnectionClosed(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            listBox1.Items.Add("Connection Closed");
            Reconnect();
            //WakeUp(e.Message);
        }

        /// <summary>
        /// 远程开机，网卡需要具备远程唤醒功能
        /// </summary>
        /// <param name="mac">网卡物理地址字符数组</param>
        public void WakeUp(byte[] mac)
        {
            UdpClient client = new UdpClient();
            client.Connect(IPAddress.Broadcast, 9090);

            byte[] packet = new byte[17 * 6];

            for (int i = 0; i < 6; i++)
                packet[i] = 0xFF;

            for (int i = 1; i <= 16; i++)
                for (int j = 0; j < 6; j++)
                    packet[i * 6 + j] = mac[j];

            int result = client.Send(packet, packet.Length);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            byte[] mac = new byte[6];
            string[] chars = txtMac.Text.Split(new char[] { ':','-' }, StringSplitOptions.RemoveEmptyEntries);
            if (chars.Length != 6)
                throw new FormatException();

            //逐个字符变为16进制字节数据
            for (int i = 0; i < 6; i++)
            {
                //message[i] = Convert.ToByte(chars[i], 16);
                mac[i] = Convert.ToByte(chars[i], 16);
            }
            WakeUp(mac);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            client.Disconnect();
        }
    }
}
